package com.yonyou.crm.sys.login.appctrl;

import com.yonyou.crm.common.enumeration.entity.EnableStateEnum;
import com.yonyou.crm.common.exception.CrmMessageException;
import com.yonyou.crm.common.login.context.LoginContextConstant;
import com.yonyou.crm.common.rest.constant.AppCodeConstant;
import com.yonyou.crm.common.rest.constant.PCCodeConstant;
import com.yonyou.crm.common.rest.util.RequestUtil;
import com.yonyou.crm.common.rest.util.ResponseUtil;
import com.yonyou.crm.csns.im.constant.ImConstant;
import com.yonyou.crm.csns.im.entity.ImVO;
import com.yonyou.crm.csns.im.rmitf.IImRmService;
import com.yonyou.crm.sys.login.rmitf.ILoginRmService;
import com.yonyou.crm.sys.role.constant.RoleTypeConstant;
import com.yonyou.crm.sys.role.entity.RoleVO;
import com.yonyou.crm.sys.role.rmitf.IRoleRmService;
import com.yonyou.crm.sys.user.entity.TypeEnum;
import com.yonyou.crm.sys.user.entity.UserVO;
import com.yonyou.iuap.auth.shiro.AuthConstants;
import com.yonyou.iuap.auth.token.ITokenProcessor;
import com.yonyou.iuap.auth.token.TokenParameter;

import net.sf.json.JSONObject;

import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Scope;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;
import org.springside.modules.security.utils.Digests;
import org.springside.modules.utils.Encodes;

import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

@RequestMapping("/{version}/msys/login")
@RestController
@Scope("prototype")
public class AppLoginCtrl {

	public static final int HASH_INTERATIONS = 1024;

	// 移动的指定为maTokenProcessor
	@Autowired()
	protected ITokenProcessor maTokenProcessor;
	@Autowired
	private ILoginRmService service;
	@Autowired
	private IImRmService imService;
	@Autowired
	private IRoleRmService roleService;

	@RequestMapping(method = RequestMethod.POST)
	public Object formLogin(@PathVariable("version") String version, HttpServletRequest request,
			HttpServletResponse response) throws CrmMessageException {

		Map<String, Object> data = new HashMap<String, Object>();
		
		JSONObject paramObj = RequestUtil.getParamObject(request);
		String userName = paramObj.getString("username");
		String passWord = paramObj.getString("password");

		if (StringUtils.isBlank(userName) || StringUtils.isBlank(passWord)) {
			throw new CrmMessageException(AppCodeConstant.ClientError, "用户名或密码不能为空！");
		}

		UserVO user = service.login(userName);
		if (user == null) {
			throw new CrmMessageException(AppCodeConstant.ServerError, "用户不存在！");
		}
		
		if (isAdmin(user.getType())) {
			throw new CrmMessageException(AppCodeConstant.ServerError, "无该终端的使用权限，请与管理员联系！");
		}

		if (user.getEnableState().intValue() == EnableStateEnum.DISABLE.getValue()) {
			throw new CrmMessageException(AppCodeConstant.ServerError, "用户已停用！");
		}
		
		if (user.getRoleId() == null || user.getRoleId().intValue() == 0) {
			throw new CrmMessageException(AppCodeConstant.ServerError, "用户还未分配角色，请与管理员联系！");
		}
		
		if (isNoOrg(user)) {
			throw new CrmMessageException(PCCodeConstant.ServiceFormVaild, "用户公司或部门信息缺失，请与联系管理员！");
		}
		
		List<RoleVO> roleList = roleService.getUserRole(user.getId());
		RoleVO roleVO = roleList.get(0);
		Integer roleType = roleVO.getType();
		if(!(RoleTypeConstant.SALESPERSON.equals(roleType+"") || RoleTypeConstant.SALESMANGER.equals(roleType+""))) {
			throw new CrmMessageException("只有销售员和销售经理两种角色类型的用户可以登录!");
		}
		// 密码加密
		byte[] hashPassword = Digests.sha1(passWord.getBytes(), Encodes.decodeHex(user.getSalt()), HASH_INTERATIONS);
		String checkPwd = Encodes.encodeHex(hashPassword);
		if (checkPwd.equals(user.getPassword())) {
			process(request, response, data, user, userName, roleType);
		} else {
			throw new CrmMessageException(AppCodeConstant.ServerError, "用户或密码输入有误！");
		}
		return ResponseUtil.getObject(data);
	}

	/**
	 * 登陆成功，返回用户信息和token 用于非登陆请求的校验 类似pc端的cookie
	 * 
	 * @param request
	 * @param response
	 * @param data
	 * @param userName
	 */
	private void process(HttpServletRequest request, HttpServletResponse response, Map<String, Object> data, UserVO user, String userName, Integer roleType) {
		TokenParameter tp = new TokenParameter();
		tp.setUserid(userName);
		tp.setLogints(String.valueOf(System.currentTimeMillis()));
		Map<String, Object> authority = new HashMap<String, Object>();
		// 租户id
		String tennantid = user.getTenantId().toString();
		// 如果有租户信息，设置，目前用户同意认证中心返回的的tenant是名称
		tp.getExt().put(AuthConstants.PARAM_TENANTID, tennantid);
		Cookie[] cookies = maTokenProcessor.getCookieFromTokenParameter(tp);
		for (Cookie cookie : cookies) {
			authority.put(cookie.getName(), cookie.getValue());
		}
		authority.put(LoginContextConstant.UserId, user.getId());
		authority.put(LoginContextConstant.OrgId, user.getOrgId());
		authority.put(LoginContextConstant.DeptId, user.getDeptId());
		//TODO获取用户角色
		authority.put(LoginContextConstant.RoleId, user.getRoleId());
		authority.put(LoginContextConstant.ROLETYPE, roleType);
		data.put("authority", authority);
		
		//设置im信息
		Map<String, Object> imMap = new HashMap<String, Object>();
		ImVO imVO = imService.getImDetail(new Long(tennantid));
		if (imVO != null) {
			imMap.put(ImConstant.EptId, imVO.getEptId());
			imMap.put(ImConstant.AppId, imVO.getAppId());
			imMap.put(ImConstant.ClientId, imVO.getClientId());
			imMap.put(ImConstant.ClientSecret, imVO.getClientSecret());
		}
		data.put("im", imMap);
	}

	private boolean isAdmin(int type) {
    	return type == TypeEnum.XTADMIN.getValue() || type == TypeEnum.JTADMIN.getValue() || type == TypeEnum.GSADMIN.getValue();
    }
	
    private boolean isNoOrg(UserVO user) {
    	return (user.getOrgId() == null || user.getOrgId().longValue() == 0 || user.getDeptId() == null || user.getDeptId().longValue() == 0);
    }
}
